#include "opencv/cv.h"
#include "opencv/highgui.h"
#include <stdio.h>
#include <stdlib.h>

#define FPS 15
#define ECHO_SAMPLING 15
#define forn(i,n) for(i=0;i<n;i++)

extern void asmRoberts(const char* src, char* dst, int ancho, int alto, int xorder, int yorder);
extern void asmSobel(const char* src, char* dst, int ancho, int alto, int xorder, int yorder);
extern void asmPrewitt(const char* src, char* dst, int ancho, int alto, int xorder, int yorder);
extern void asmFrei(const char* src, char* dst, int ancho, int alto, int xorder, int yorder);

int main( int argc, char** argv ){
	
	int pscreen=0;
   IplImage * src = 0;
   IplImage * dst = 0;
   IplImage * dst_ini = 0;

	cvNamedWindow("camara",1);
	int state = 0;
	
	IplImage* e[ECHO_SAMPLING];
	int echo_index = 0;
	
	// create capture
	CvCapture* capture = (argc==2)?cvCaptureFromAVI(argv[1]):cvCaptureFromCAM(-1);
	if(!capture){
		printf("%s\n","Error al conectar la camara");
		return -1;
	}
	IplImage* frame = cvQueryFrame(capture);
	if((src = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1))==0) return -1;
	if((dst = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1))==0) return -1;
	
	IplImage* aux;
	if((aux = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1))==0) return -1;

	int i;
	for(i=0;i<ECHO_SAMPLING;i++) if((e[i] = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1))==0) return -1;

	cvMoveWindow("camara",100,100);

	while(1){
		frame = cvQueryFrame(capture);
		if(state==0){
			cvCvtColor(frame,dst,CV_BGR2GRAY); 										// convierte RGB a Grayscale
		}else if(state==1){
			cvCvtColor(frame,src,CV_BGR2GRAY); // convierte RGB a Grayscale
			asmSobel(src->imageData, dst->imageData, src->width, src->height, 1, 0); // aplico la mascara de sobel en X
		}else if(state==2){
			cvCvtColor(frame,src,CV_BGR2GRAY); // convierte RGB a Grayscale
			asmSobel(src->imageData, dst->imageData, src->width, src->height, 0, 1); // aplico la mascara de sobel en Y
		}else if(state==3){
			cvCvtColor(frame,src,CV_BGR2GRAY); // convierte RGB a Grayscale
			asmSobel(src->imageData, dst->imageData, src->width, src->height, 1, 1); // aplico la mascara de sobel en X e Y
		}else if(state==4){
			cvCvtColor(frame,src,CV_BGR2GRAY); // convierte RGB a Grayscale
			//asmWTF(src->imageData, dst->imageData, src->width, src->height); // aplico la mascara WTF
		}else if(state==5){
			cvCvtColor(frame,src,CV_BGR2GRAY); // convierte RGB a Grayscale
			asmPrewitt(src->imageData, dst->imageData, src->width, src->height, 1, 1); // aplico la mascara Prewitt
		}else if(state==6){
			cvCvtColor(frame,src,CV_BGR2GRAY); // convierte RGB a Grayscale
			//asmMono(src->imageData, dst->imageData, src->width, src->height); // aplico la mascara Monocromo
		}else if(state==7){
			cvCvtColor(frame,src,CV_BGR2GRAY); // convierte RGB a Grayscale
			asmRoberts(src->imageData, dst->imageData, src->width, src->height, 1, 1); // aplico la mascara Roberts
		}else if(state==8){
			cvCvtColor(frame,e[echo_index],CV_BGR2GRAY); // convierte RGB a Grayscale
			//asmRoberts(e[(echo_index+1)%ECHO_SAMPLING]->imageData,src->imageData,src->width, src->height, 1, 1);
			//asmSobel(e[(echo_index+(ECHO_SAMPLING/2))%ECHO_SAMPLING]->imageData,e[(echo_index+1)%ECHO_SAMPLING]->imageData,aux->width, aux->height, 1, 1);
			//merge( e[(echo_index+1)%ECHO_SAMPLING]->imageData , src->imageData, aux->imageData, dst->width, dst->height);
			//merge( e[echo_index]->imageData , aux->imageData, dst->imageData, dst->width, dst->height);
			asmSobel(e[(echo_index+1)%ECHO_SAMPLING]->imageData,aux->imageData,aux->width, aux->height, 1, 1);
//			merge( e[echo_index]->imageData , aux->imageData, dst->imageData, dst->width, dst->height);
			echo_index++;
			echo_index %= ECHO_SAMPLING;
		}
		cvShowImage("camara",dst);
		int key = cvWaitKey(1000/FPS);
		if((char)key==27){
			break;
		}else if( '0'<=(char)key && (char)key<='9' ){
			state = atoi((char*)&key);
			//printf("%d\n",state);
		}else if((char)key=='p'){
			char psname[200];
			char* ss="screenshot";
			char* jpg=".jpg";
			sprintf(psname,"%s%d%s",ss,pscreen,jpg);
			pscreen++;
			cvSaveImage(psname, dst);
			printf("%s %s\n","output written to",psname);
		}
	}
	cvReleaseCapture(&capture);
	cvDestroyWindow("camara");
   return 0;
}


